【Pwn 笔记】IO FILE 利用链汇总(待补充)

从零开始的 IO FILE 生活

(缺省)

(缺省)

1
0x7f34f91b13a3 <_IO_file_overflow+163>    or     ah, 8

vtable劫持以及绕过

这里的伪造一般建议在 bss 段伪造,修改_IO_list_all的值,进行 FSOP

__IO_2_1_stdin_ + 0xe0处伪造也行,即_IO_wide_data_0,一般不会对程序有啥影响

要注意fp->_lock处一定要有一个值为 0 的地址,一般写__free_hook__malloc_hook的地址

_IO_str_jumps

主要用_IO_str_jumps内的两个地址

_IO_str_overflow

可以这么伪造

1
2
3
4
5
6
7
fp->_flags = 0
fp->_IO_write_base = 0
fp->_IO_write_ptr = addr_rdx
fp->_IO_buf_base = 0
fp->_IO_buf_end = (addr_rdi - 100) / 2
fp->_mode = 0
vtable = addr_IO_str_jumps

这里要满足_IO_write_ptr >= _IO_buf_end,一般写的时候让addr_rdx等于addr_rdi就行了

该伪造方法的完整利用链有:

1
2
malloc_printerr -> __libc_message -> __GI_abort -> _IO_flush_all_lockp -> _IO_str_overflow
__run_exit_handlers -> _IO_cleanup -> _IO_flush_all_lockp -> _IO_str_overflow

如果 addr_rdi 的地址以奇数结尾,为了避免除法向下取整的干扰,可以将该地址加 1

进入_IO_str_overflow后,值addr_rdi会存在 rdi 寄存器和 rbx 寄存器里,值addr_rdx会存在 rdx 寄存器里

libc-2.27.so及之前,程序在_IO_str_overflow里可以通过call qword ptr [rbx + 0xe0]来执行指定的函数

libc-2.29.so及之后,程序在__GI__IO_str_overflow里不再使用上面的指令,而是调用call malloc@plt

那么利用手段就要改变一下,原先是在&_IO_list_all.file._flags + 0xe0的位置,换算成熟悉的地址也就是&_IO_list_all.vtable + 8

原本应该在这里写入要执行的函数地址,但是到了libc-2.29.so及之后,利用手法就变成改写__malloc_hook为要执行的函数地址了

_IO_str_finish

可以这么伪造

1
2
3
4
5
6
7
fp->_flags = 0
fp->_IO_write_ptr = 0xffffffff
fp->_IO_write_base = 0
fp->_wide_data->_IO_buf_base = addr_rdi(也就是 fp->_IO_write_end)
fp->_flags2 = 0
fp->_mode = 0
vtable = addr_IO_str_jumps - 8

该伪造方法的完整利用链有:

1
2
malloc_printerr -> __libc_message -> __GI_abort -> _IO_flush_all_lockp -> _IO_str_finish
__run_exit_handlers -> _IO_cleanup -> _IO_flush_all_lockp -> _IO_str_finish

libc-2.27.so及之前,程序在_IO_str_finish里可以通过call qword ptr [rbx + 0xe8]来执行指定的函数

libc-2.29.so及之后,程序在_IO_str_finish里不再使用上面的指令,而是调用call free@plt

那么利用手段就要改变一下,原先是在&_IO_list_all.file._flags + 0xe8的位置,换算成熟悉的地址也就是&_IO_list_all.vtable + 0x10

原本应该在这里写入要执行的函数地址,但是到了libc-2.29.so及之后,利用手法就变成改写__free_hook为要执行的函数地址了

_IO_wstr_jumps

基本同_IO_str_jumps的利用


IO FILE 表及对应偏移

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
0x0   _flags
0x8 _IO_read_ptr
0x10 _IO_read_end
0x18 _IO_read_base
0x20 _IO_write_base
0x28 _IO_write_ptr
0x30 _IO_write_end
0x38 _IO_buf_base
0x40 _IO_buf_end
0x48 _IO_save_base
0x50 _IO_backup_base
0x58 _IO_save_end
0x60 _markers
0x68 _chain
0x70 _fileno
0x74 _flags2
0x78 _old_offset
0x80 _cur_column
0x82 _vtable_offset
0x83 _shortbuf
0x88 _lock
0x90 _offset
0x98 _codecvt
0xa0 _wide_data
0xa8 _freeres_list
0xb0 _freeres_buf
0xb8 __pad5
0xc0 _mode
0xc4 _unused2
0xd8 vtable

参考资料

1
2
https://ray-cp.github.io/archivers/IO_FILE_vtable_check_and_bypass
https://firmianay.gitbooks.io/ctf-all-in-one/doc/4.13_io_file.html
文章目录
  1. 1. (缺省)
    1. 1.1. (缺省)
  2. 2. vtable劫持以及绕过
    1. 2.1. _IO_str_jumps
      1. 2.1.1. _IO_str_overflow
      2. 2.1.2. _IO_str_finish
    2. 2.2. _IO_wstr_jumps
  3. 3. IO FILE 表及对应偏移
  4. 4. 参考资料
|